import os;
import sys;

sys.path.append(os.environ['WEBAPP_ROOT_PATH']);
sys.path.append(os.environ['CPPWEB_INSTALL_HOME'] + '/library/python');

import imp;
import dbx;
import stdx;
import webx;
import time;

cgimap = None;
cgimapfile = None;
cgimaptime = None;

def setup(path):
	global cgimapfile;
	global cgimaptime;
	if path:
		try:
			webx.InitWebapp(path);
			if cgimapfile == None: cgimapfile = os.path.dirname(os.path.realpath(__file__)) + '/' + '__init__.py';
			cgimaptime = os.path.getmtime(cgimapfile);
		except BaseException as e:
			webx.LogTrace('ERR', 'system error[%s]' % str(e), e);
			return False;
	webx.InitDatabase();
	reloadpython();
	return True;

def getcgimap():
	global cgimap;
	reloadpython();
	return cgimap;

def reloadpython():
	global cgimap;
	try:
		import pyc.__init__;
		cgimap = imp.reload(pyc.__init__).getcgimap();
		return True;
	except BaseException as e:
		webx.LogTrace('ERR', 'reload python cgimap failed', e);
		return False;

def gethttpstatus(code):
	if code == stdx.TIMEOUT: return 401;
	if code == stdx.SYSBUSY: return 503;
	if code == stdx.DAYLIMIT: return 503;
	if code == stdx.PARAMERR: return 400;
	if code == stdx.AUTHFAIL: return 403;
	return 500;

def process(path, head, data):
	try:
		if cgimapfile:
			global cgimaptime;
			tm = os.path.getmtime(cgimapfile);
			if tm > cgimaptime and reloadpython(): cgimaptime = tm + 0.001;
		key = path.lower();
		if key not in cgimap:
			if key == 'reloadpython':
				if reloadpython(): return stdx.json({'code': stdx.OK});
				else: return stdx.json({'code': stdx.SYSERR});
			return stdx.NOTFOUND;
		app = HttpProcesser(path, head, data);
		res = cgimap[key](app);
		return (res, app.getHeader());
	except stdx.CommException as e:
		webx.LogTrace('ERR', str(e), e);
		return (stdx.json({'code': e.getErrorCode(), 'desc': e.getErrorString()}), {':status': gethttpstatus(e.getErrorCode())});
	except BaseException as e:
		webx.LogTrace('ERR', str(e), e);
		return (stdx.json({'code': stdx.SYSERR, 'desc': 'system error'}), {':status': gethttpstatus(stdx.SYSERR)});

class HttpProcesser(webx.HttpRequest):
	def __init__(self, path, head, data):
		webx.HttpRequest.__init__(self, head, data);
		self._rsphead = {};
		self._param = data;
		self._path = path;
	def __len__(self):
		return len(self._data);
	def __getattr__(self, attr):
		return self.getParameter(attr);
	def simpleResponse(self, code):
		return "{\"code\":" + str(code) + "}";
	def setStatus(self, status):
		self._rsphead[':status'] = status;
		return self;
	def setHeader(self, key, val):
		self._rsphead[key] = val;
		return self;
	def setContentType(self, mime):
		return self.setHeader('Content-Type', mime);
	def getHeader(self, key = None):
		if key: return self._rsphead[key];
		else: return self._rsphead;
	def dbconnect(self, dbid = None):
		return webx.GetDBConnect(dbid);
	def trace(self, tag, msg, err = None):
		webx.LogTrace(tag, msg, err);
		return self;
	def getSessionId(self):
		sid = self.getHeadParameter('Cookie');
		if len(sid) <= 0:
			sid = self.getHeadParameter('cookie');
			if len(sid) <= 0: return self.getParameter('sid');
		sid = sid.replace(' ', '');
		pos = sid.find('sid=');
		if pos < 0: return self.getParameter('sid');
		pos = pos + 4;
		end = sid.find(';', pos);
		if end < pos: return sid[pos:].lstrip(' \r\n\t').rstrip(' \r\n\t');
		else: return sid[pos:end].lstrip(' \r\n\t').rstrip(' \r\n\t');
	def setSessionId(self, sid):
		self.setHeader('Set-Cookie', 'sid=' + sid + ';max-age=' + str(90 * 24 * 3600) + ';HttpOnly');
	def setSession(self, key, val, sid = None):
		if sid == None: sid = self.getSessionId();
		if sid: return webx.SetSession(sid, key, val);
		else: return stdx.PARAMERR;
	def getSession(self, key = None, sid = None):
		if sid == None: sid = self.getSessionId();
		if sid: return webx.GetSession(sid, key);
		return None;
	def checkLogin(self, data = None, sid = None):
		if sid == None: sid = self.getSessionId();
		if sid == None or len(sid) < 8: stdx.Throw(stdx.TIMEOUT);
		msg = webx.GetRemoteResult('CheckLogin', 'flag=C&sid=' + sid, None, self.getHeadParameter('Cookie'));
		msg = stdx.parse(msg);
		if msg['code'] < 0:
			if 'desc' in msg:
				stdx.Throw(msg['code'], msg['desc']);
			else:
				stdx.Throw(msg['code']);
		if 'user' in msg:
			if webx.CheckAccess(self._path, self._param, msg['grouplist']) < 0:
				stdx.Throw(stdx.AUTHFAIL);
			if data == None: return msg['user'];
			for key in msg: data[key] = msg[key];
			return msg['user'];
		stdx.Throw(stdx.SYSERR);
	def getUserData(self, keylist = None, sid = None):
		res = [];
		data = {};
		self.checkLogin(data, sid);
		if isinstance(keylist, list) or isinstance(keylist, tuple):
			for key in keylist:
				if key in data: res.append(data[key]);
				else: res.append(None);
		else:
			key = str(keylist);
			if key in data: res.append(data[key]);
			else: res.append(None);
		return res;